package com.sfx.concurrent.demo.线程基础;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import lombok.extern.slf4j.Slf4j;

@Slf4j(topic = "c.DeadLock")
public class DeadLock {
    private static final Lock lockA = new ReentrantLock();
    private static final Lock lockB = new ReentrantLock();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            try {
                if (lockA.tryLock(1000, TimeUnit.MILLISECONDS)) {
                    log.debug("lockA");
                    // 线程t1获取了A对象的锁, 1s 之后,又要获取B对象的锁
                    try {
                        if (lockB.tryLock(1000, TimeUnit.MILLISECONDS)) {
                            log.debug("lockB");
                            log.debug("操作...");
                        } else {
                            log.debug("获取锁B超时，放弃操作...");
                        }
                    } finally {
                        lockB.unlock();
                    }
                } else {
                    log.debug("获取锁A超时，放弃操作...");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lockA.unlock();
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            try {
                if (lockA.tryLock(1000, TimeUnit.MILLISECONDS)) {
                    log.debug("lockB");
                    // 线程t2获取了B对象的锁, 1s 之后,又要获取A对象的锁
                    try {
                        if (lockB.tryLock(1000, TimeUnit.MILLISECONDS)) {
                            log.debug("lockA");
                            log.debug("操作...");
                        } else {
                            log.debug("获取锁A超时，放弃操作...");
                        }
                    } finally {
                        lockB.unlock();
                    }
                } else {
                    log.debug("获取锁B超时，放弃操作...");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lockA.unlock();
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}
